package com.alibaba.cloud.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.URI;
import java.net.URL;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * workId 工具类.
 */
public class WorkIdUtil {

	/** The Constant log. */
	private static final Logger log = LoggerFactory.getLogger(WorkIdUtil.class);

	/** The Constant CONNECT_TIMEOUT. */
	private static final int CONNECT_TIMEOUT = 1000;

	/** The Constant READ_TIMEOUT. */
	private static final int READ_TIMEOUT = 1500;

	/** The Constant CHARSET. */
	private static final String CHARSET = "UTF-8";

	/**
	 * Gets the host info.
	 *
	 * @return the host info
	 */
	public static Map<String, Object> getHostInfo() {
		Map<String, Object> params = new HashMap<>();
		try {
			InetAddress inetAddress = InetAddress.getLocalHost();
			byte[] macBytes = NetworkInterface.getByInetAddress(inetAddress).getHardwareAddress();
			params.put("macAddress", getMacAddress(macBytes));
			params.put("hostName", inetAddress.getHostName());
			params.put("ipAddress", inetAddress.getHostAddress());
		} catch (Exception exception) {
			log.warn("获取HostInfo失败", exception);
		}
		return params;
	}

	/**
	 * Gets the mac address.
	 *
	 * @param macBytes the mac bytes
	 * @return the mac address
	 */
	private static String getMacAddress(byte[] macBytes) {
		StringBuffer buffer = new StringBuffer("");
		for (int i = 0; i < macBytes.length; i++) {
			buffer.append(String.format("%02X%s", macBytes[i], (i < macBytes.length - 1) ? "-" : ""));
		}
		return buffer.toString();
	}

	/**
	 * Invoke url.
	 *
	 * @param requestUrl  the request url
	 * @param requestJson the request json
	 * @param headers     the headers
	 * @return the string
	 */
	public static String invokeUrl(String requestUrl, String requestJson, Map<String, String> headers) {
		URL url = null;
		HttpURLConnection httpURLConnection = null;
		PrintWriter out = null;
		BufferedReader in = null;
		try {
			// 创建和初始化连接
			url = URI.create(requestUrl).toURL();
			httpURLConnection = (HttpURLConnection) url.openConnection();
			httpURLConnection.setRequestProperty("accept", "*/*");
			httpURLConnection.setRequestProperty("content-type", "application/json");
			httpURLConnection.setRequestMethod("POST");
			// 发送POST请求必须设置如下两行
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setDoInput(true);
			// 设置连接超时时间
			httpURLConnection.setConnectTimeout(CONNECT_TIMEOUT);
			// 设置读取超时时间
			httpURLConnection.setReadTimeout(READ_TIMEOUT);
			// 指定请求header参数
			if (headers != null && headers.size() > 0) {
				Set<String> headerSet = headers.keySet();
				for (String key : headerSet) {
					httpURLConnection.setRequestProperty(key, headers.get(key));
				}
			}
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(new OutputStreamWriter(httpURLConnection.getOutputStream(), CHARSET));
			// 发送请求参数
			out.print(requestJson);
			// flush输出流的缓冲
			out.flush();
			// 接收返回结果
			StringBuilder result = new StringBuilder();
			in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), CHARSET));
			if (in != null) {
				String line = "";
				while ((line = in.readLine()) != null) {
					result.append(line);
				}
			}
			return result.toString();
		} catch (Exception e) {
			log.error("调用地址: {} 失败！请求参数: {}异常:{}", requestUrl, requestJson, e);
			// 处理错误流，提高http连接被重用的几率
			try {
				InputStream es = httpURLConnection.getErrorStream();
				if (es != null) {
					es.close();
				}
			} catch (IOException exception) {
				log.error("HttpUtil 调用获取workId 异常,{}", exception);
			}
		} finally {
			if (out != null) {
				out.close();
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					log.error("关闭流异常,{}", e);
				}
			}
			// 关闭连接
			if (httpURLConnection != null) {
				httpURLConnection.disconnect();
			}
		}
		return null;
	}

	/**
	 * Invoke SSL url.
	 *
	 * @param requestUrl  the request url
	 * @param requestJson the request json
	 * @param headers     the headers
	 * @return the string
	 */
	public static String invokeSSLUrl(String requestUrl, String requestJson, Map<String, String> headers) {
		PrintWriter out = null;
		BufferedReader in = null;
		HttpsURLConnection httpsURLConnection = null;
		try {
			// 创建和初始化连接
			URL httpsUrl = URI.create(requestUrl).toURL();
			SSLContext sslcontext = SSLContext.getInstance("SSL", "SunJSSE");
			sslcontext.init(null, new TrustManager[] { new EhomepayX509TrustManager() },
					new java.security.SecureRandom());
			HostnameVerifier ignoreHostnameVerifier = new EhomepayHostnameVerifier();
			HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
			HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
			httpsURLConnection = (HttpsURLConnection) httpsUrl.openConnection();
			httpsURLConnection.setRequestProperty("accept", "*/*");
			httpsURLConnection.setRequestProperty("content-type", "application/json");
			httpsURLConnection.setRequestMethod("post");
			// 设置连接超时时间
			httpsURLConnection.setConnectTimeout(CONNECT_TIMEOUT);
			// 设置读取超时时间
			httpsURLConnection.setReadTimeout(READ_TIMEOUT);
			// 发送POST请求必须设置如下两行
			httpsURLConnection.setDoOutput(true);
			httpsURLConnection.setDoInput(true);
			httpsURLConnection.setInstanceFollowRedirects(false);
			// 指定请求header参数
			if (headers != null && headers.size() > 0) {
				Set<String> headerSet = headers.keySet();
				for (String key : headerSet) {
					httpsURLConnection.setRequestProperty(key, headers.get(key));
				}
			}
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(new OutputStreamWriter(httpsURLConnection.getOutputStream(), CHARSET));
			// 发送请求参数
			out.print(requestJson);
			// flush输出流的缓冲
			out.flush();
			// 接收返回结果
			StringBuilder result = new StringBuilder();
			in = new BufferedReader(new InputStreamReader(httpsURLConnection.getInputStream(), CHARSET));
			if (in != null) {
				String line = "";
				while ((line = in.readLine()) != null) {
					result.append(line);
				}
			}
			return result.toString();
		} catch (Exception e) {
			log.error("调用地址: {} 失败！请求参数: {}", requestUrl, requestJson, e);
			// 处理错误流，提高http连接被重用的几率
			try {
				InputStream es = httpsURLConnection.getErrorStream();
				if (es != null) {
					es.close();
				}
			} catch (IOException exception) {
				log.error("获取workId 异常,{}", exception);
			}
		} finally {
			if (out != null) {
				out.close();
			}
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					log.error("关闭流异常,{}", e);
				}
			}
			// 关闭连接
			if (httpsURLConnection != null) {
				httpsURLConnection.disconnect();
			}
		}
		return null;
	}
}

class EhomepayX509TrustManager implements X509TrustManager {

	@Override
	public void checkClientTrusted(X509Certificate certificates[], String authType) throws CertificateException {
	}

	@Override
	public void checkServerTrusted(X509Certificate[] ax509certificate, String s) throws CertificateException {
	}

	@Override
	public X509Certificate[] getAcceptedIssuers() {
		return null;
	}
}

class EhomepayHostnameVerifier implements HostnameVerifier {

	@Override
	public boolean verify(String hostname, SSLSession session) {
		return true;
	}

}
